package cn.cdeden.auth.service;

import cn.cdeden.common.core.exception.ServiceException;
import cn.cdeden.system.api.RemoteLgtypeConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.*;

@Slf4j
@Component
@RequiredArgsConstructor
public class AdAuthService {

    @DubboReference
    private RemoteLgtypeConfigService remoteLgtypeConfigService;

    private static final String LOGIN_TYPE = "ad";
    private static final String AD_DOMAIN_PREFIX_KEY = "ad_domain_domainPerfix";
    private static final String AD_DOMAIN_URL_KEY = "ad_domain_url";
    private static final String LDAP_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
    private static final String LDAP_AUTH_METHOD = "simple";

    /**
     * 验证用户密码
     *
     * @param username 用户名
     * @param password 密码
     * @return true 表示验证通过，否则抛出异常
     */
    public Boolean ldapVerify(String username, String password) {
        LdapContext ldapContext = null;
        try {
            // 获取LDAP配置信息
            Map<String, String> config = remoteLgtypeConfigService.getAllConfigByKeys(LOGIN_TYPE);
            String ldapUrl = config.get(AD_DOMAIN_URL_KEY);
            if (ldapUrl == null || ldapUrl.isEmpty()) {
                throw new ServiceException("AD验证失败：LDAP配置信息缺失");
            }

            // 构建用户名
            String domainPrefix = config.get(AD_DOMAIN_PREFIX_KEY);
            if (domainPrefix != null && !domainPrefix.isEmpty()) {
                username = domainPrefix + username;
            }

            // 构建LDAP连接参数
            Hashtable<String, String> env = new Hashtable<>();
            env.put(Context.SECURITY_PRINCIPAL, username);
            env.put(Context.SECURITY_CREDENTIALS, password);
            env.put(Context.PROVIDER_URL, ldapUrl);
            env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_FACTORY);
            env.put(Context.SECURITY_AUTHENTICATION, LDAP_AUTH_METHOD);

            // 初始化 LDAP 连接
            ldapContext = new InitialLdapContext(env, null);
            return true;
        } catch (AuthenticationException e) {
            e.printStackTrace();
            throw new ServiceException("AD验证失败：用户名或密码错误");
        } catch (Exception e) {
            throw new ServiceException("AD验证失败：" + e.getMessage());
        } finally {
            // 关闭 LDAP 连接
            if (ldapContext != null) {
                try {
                    ldapContext.close();
                } catch (NamingException e) {
                    e.printStackTrace(); // 或记录到日志
                }
            }
        }
    }

}
